package com.redepronik.negosysfab.invfac.report;

import static com.redepronik.negosys.utils.Utils.multiplicar;
import static com.redepronik.negosys.utils.Utils.multiplicarDivide;
import static com.redepronik.negosys.utils.Utils.valorConIva;
import static com.redepronik.negosys.utils.Utils.valorConPorcentaje;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.redepronik.negosys.invfac.entity.Bodega;
import com.redepronik.negosys.invfac.entity.Grupo;
import com.redepronik.negosys.invfac.entity.Kardex;
import com.redepronik.negosys.invfac.entity.Producto;
import com.redepronik.negosys.invfac.entity.Productounidad;
import com.redepronik.negosys.invfac.entity.TipoPrecioProducto;
import com.redepronik.negosys.invfac.entityAux.ControlInventarioReporte;
import com.redepronik.negosys.invfac.entityAux.KardexReporte;
import com.redepronik.negosys.invfac.entityAux.PedidoStockProductoReporte;
import com.redepronik.negosys.invfac.entityAux.PrecioGrupoProductoReporte;
import com.redepronik.negosys.invfac.entityAux.PrecioProductoReporte;
import com.redepronik.negosys.invfac.entityAux.ProductoReporte;
import com.redepronik.negosys.invfac.service.BodegaService;
import com.redepronik.negosys.invfac.service.GrupoService;
import com.redepronik.negosys.invfac.service.KardexService;
import com.redepronik.negosys.invfac.service.ProductoService;
import com.redepronik.negosys.utils.service.ReporteService;

@Controller
public class ProductoReport {

	@Autowired
	private ReporteService reporteService;

	@Autowired
	private ProductoService productoService;

	@Autowired
	private GrupoService grupoService;

	@Autowired
	private KardexService kardexService;

	@Autowired
	private BodegaService bodegaService;

	private List<Producto> listProductos;
	private String nombreProducto;
	private Producto producto;
	private Bodega bodega;

	private boolean bnVendedor;

	private Date fechaInicio;
	private Date fechaFinal;

	public ProductoReport() {
		listProductos = new ArrayList<Producto>();
		producto = new Producto();
		bodega = new Bodega();
		bnVendedor = false;
	}

	public Bodega getBodega() {
		return bodega;
	}

	public Date getFechaFinal() {
		return fechaFinal;
	}

	public Date getFechaInicio() {
		return fechaInicio;
	}

	public List<Producto> getListProductos() {
		return listProductos;
	}

	public String getNombreProducto() {
		return nombreProducto;
	}

	public Producto getProducto() {
		return producto;
	}

	public boolean isBnVendedor() {
		return bnVendedor;
	}

	public PrecioProductoReporte metodo(Producto producto, int bodegaId) {
		producto = productoService.obtenerPorProductoId(producto
				.getProductoid());
		Kardex kardex = kardexService.obtenerSaldoActual(producto.getEan(),
				bodegaId);

		int cantidad = 0;
		if (kardex != null && kardex.getCantidad() > 0)
			cantidad = kardex.getCantidad();

		TipoPrecioProducto tpp = productoService.obtenerValorPvp(producto
				.getTipoPrecioProductos());

		if (tpp == null)
			tpp = producto.getTipoPrecioProductos().size() >= 2 ? producto
					.getTipoPrecioProductos().get(1) : producto
					.getTipoPrecioProductos().get(0);

		BigDecimal valor = tpp.getValor();
		if (!tpp.getPorcentajepreciofijo())
			valor = multiplicarDivide(valor.subtract(kardex.getPrecio()), 100,
					kardex.getPrecio());

		BigDecimal preciouniventa = valorConPorcentaje(kardex.getPrecio(),
				valor);
		BigDecimal preciounicosto = kardex.getPrecio();

		if (producto.getIva()) {
			preciouniventa = valorConIva(preciouniventa);
			preciounicosto = valorConIva(preciounicosto);
		}

		String sinIva = "";
		String conIva = "";

		for (Productounidad pu : producto.getProductounidads()) {
			Integer can = 1;
			for (int i = producto.getProductounidads().indexOf(pu); i >= 0; i--)
				can = can * producto.getProductounidads().get(i).getCantidad();

			sinIva = sinIva + " " + pu.getUnidad().getAbreviatura() + " - "
					+ multiplicar(preciounicosto, can) + "  || ";

			conIva = conIva + " " + pu.getUnidad().getAbreviatura() + " - "
					+ multiplicar(preciouniventa, can) + "  || ";
		}

		return new PrecioProductoReporte(producto.getEan(),
				producto.getNombreimprimir(), cantidad,
				productoService.convertirUnidadString(cantidad,
						producto.getProductounidads()), valor, sinIva, conIva);
	}

	public void obtenerProducto() {
		producto = productoService.obtenerPorProductoId(producto
				.getProductoid());
	}

	public void obtenerProductos() {
		if (!nombreProducto.equals(null) && bodega.getBodegaid() != 0)
			listProductos = productoService.obtenerPorEanAndBodega(
					nombreProducto, bodega.getBodegaid());
	}

	public void reporteControlInventario(ActionEvent actionEvent) {
		if (bodega.getBodegaid() != 0) {
			bodega = bodegaService.obtenerPorBodegaId(bodega.getBodegaid());
			List<ControlInventarioReporte> lista = new ArrayList<ControlInventarioReporte>();
			for (ControlInventarioReporte cir : productoService
					.obtenerControlInventario(bodega.getBodegaid())) {
				Kardex kardex = kardexService.obtenerSaldoActual(cir.getEan(),
						bodega.getBodegaid());

				if (kardex != null)
					lista.add(new ControlInventarioReporte(cir.getId(), cir
							.getEan(), cir.getNombre(), kardex.getCantidad()));
			}

			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("bodega", bodega.getNombre());

			reporteService.generarReportePDF(lista, parametros,
					"ControlInventario");
		}
		bodega = new Bodega();
	}

	public void reporteKardex(ActionEvent actionEvent) {
		if (fechaInicio == null || fechaFinal == null
				|| fechaInicio.before(fechaFinal)) {
			List<KardexReporte> list = kardexService.generarkardex(producto,
					fechaInicio, fechaFinal, bodega);

			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("nomPro", producto.getNombreimprimir());
			parametros.put("gruPro", producto.getGrupo().getNombre());
			parametros.put("canMinPro", producto.getCantidadminima());
			reporteService.generarReportePDF(list, parametros, "Kardex");
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR,
					"ERROR",
					"La Fecha de Inicio tiene que ser antes que la Fecha Final");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
		bodega = new Bodega();
	}

	public void reporteListaPrecioProducto(ActionEvent actionEvent) {
		if (bodega.getBodegaid() != 0) {
			bodega = bodegaService.obtenerPorBodegaId(bodega.getBodegaid());
			List<PrecioGrupoProductoReporte> list = new ArrayList<PrecioGrupoProductoReporte>();
			for (Grupo grupo : grupoService.obtenerProductosGrupo()) {
				List<Producto> lista = productoService
						.obtenerPorBodegaAndGrupo(bodega.getBodegaid(),
								grupo.getGrupoid());

				if (lista != null && !lista.isEmpty()) {
					List<PrecioProductoReporte> list1 = new ArrayList<PrecioProductoReporte>();
					for (Producto producto : lista)
						list1.add(metodo(producto, bodega.getBodegaid()));

					list.add(new PrecioGrupoProductoReporte(grupo.getNombre(),
							list1));
				}
			}

			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("bodega", bodega.getNombre());
			reporteService.generarReportePDF(list, parametros,
					bnVendedor ? "ListaPrecioProductoVendedor"
							: "ListaPrecioProducto");
			bnVendedor = false;
		}
		bodega = new Bodega();
	}

	public void reportePedidoStockProducto(ActionEvent actionEvent) {
		if (bodega.getBodegaid() != 0) {
			bodega = bodegaService.obtenerPorBodegaId(bodega.getBodegaid());
			List<PedidoStockProductoReporte> list = new ArrayList<PedidoStockProductoReporte>();
			for (Producto producto : productoService.obtenerPorBodega(bodega
					.getBodegaid())) {
				Kardex kardex = kardexService.obtenerSaldoActual(
						producto.getEan(), bodega.getBodegaid());

				if (kardex != null
						&& kardex.getCantidad() < producto.getCantidadminima())
					list.add(new PedidoStockProductoReporte(
							producto.getEan(),
							producto.getNombreimprimir(),
							kardex.getCantidad(),
							producto.getCantidadminima() - kardex.getCantidad(),
							producto.getCantidadminima()));

			}
			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("bodega", bodega.getNombre());

			reporteService.generarReportePDF(list, parametros,
					"PedidoStockProducto");
		}
		bodega = new Bodega();
	}

	public void reporteProducto(ActionEvent actionEvent) {
		List<Producto> list = productoService.obtener();
		Map<String, Object> parametros = new HashMap<String, Object>();
		reporteService.generarReportePDF(list, parametros, "Producto");
	}

	public void reporteProductoBodega(ActionEvent actionEvent) {
		if (bodega.getBodegaid() != 0) {
			bodega = bodegaService.obtenerPorBodegaId(bodega.getBodegaid());
			List<ProductoReporte> list = new ArrayList<ProductoReporte>();
			if (producto == null) {
				for (Grupo grupo : grupoService.obtenerProductosGrupo()) {
					for (Producto producto : productoService
							.obtenerPorBodegaAndGrupo(bodega.getBodegaid(),
									grupo.getGrupoid())) {
						Kardex kardex = kardexService.obtenerSaldoActual(
								producto.getEan(), bodega.getBodegaid());
						int cantidad = kardex != null ? kardex.getCantidad()
								: 0;
						list.add(new ProductoReporte(producto, grupo, cantidad));
					}
				}
			} else {
				Kardex kardex = kardexService.obtenerSaldoActual(
						producto.getEan(), bodega.getBodegaid());
				int cantidad = kardex != null ? kardex.getCantidad() : 0;
				list.add(new ProductoReporte(producto, producto.getGrupo(),
						cantidad));
			}
			Map<String, Object> parametros = new HashMap<String, Object>();
			parametros.put("bodega", bodega.getNombre());
			reporteService
					.generarReportePDF(list, parametros, "ProductoBodega");
		}
		bodega = new Bodega();
	}

	public void reporteProductoGrupo(ActionEvent actionEvent) {
		List<Grupo> list = grupoService.obtenerProductosGrupo();
		Map<String, Object> parametros = new HashMap<String, Object>();
		reporteService.generarReportePDF(list, parametros, "ProductoGrupo");
	}

	public void setBnVendedor(boolean bnVendedor) {
		this.bnVendedor = bnVendedor;
	}

	public void setBodega(Bodega bodega) {
		this.bodega = bodega;
	}

	public void setFechaFinal(Date fechaFinal) {
		this.fechaFinal = fechaFinal;
	}

	public void setFechaInicio(Date fechaInicio) {
		this.fechaInicio = fechaInicio;
	}

	public void setListProductos(List<Producto> listProductos) {
		this.listProductos = listProductos;
	}

	public void setNombreProducto(String nombreProducto) {
		this.nombreProducto = nombreProducto;
	}

	public void setProducto(Producto producto) {
		this.producto = producto;
	}

}